﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DotNet.Random.Date
{
    /// <summary>
    /// 日期随机类，继承了IDateTimeRandService
    /// 此类有以下属性
    /// Year:年
    /// Month:月
    /// Day:日
    /// </summary>
    public class DateRandService : DotNet.Random.Interface.IDateTimeRandService
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="DateRandService" /> class.
        /// </summary>
        /// <param name="year">The year.</param>
        /// <param name="month">The month.</param>
        /// <param name="day">The day.</param>
        /// <exception cref="System.ArgumentNullException">year is null</exception>
        public DateRandService(YearRandService year, MonthRandService month, DayRandService day = null)
        {
            if (year == null)
            {
                throw new ArgumentNullException("year is null");
            }
            if (month == null)
            {
                throw new ArgumentNullException("month is null");
            }
            this.YearRand = year;
            this.MonthRand = month;
            this.DayRand = day;
        }

        /// <summary>
        /// Gets or sets the year rand.
        /// 年随机属性
        /// </summary>
        /// <value>
        /// The year rand.
        /// </value>
        protected YearRandService YearRand { get; set; }

        /// <summary>
        /// Gets or sets the month rand.
        /// 月随机属性
        /// </summary>
        /// <value>
        /// The month rand.
        /// </value>
        protected MonthRandService MonthRand { get; set; }

        /// <summary>
        /// Gets or sets the day rand.
        /// 日随机属性
        /// </summary>
        /// <value>
        /// The day rand.
        /// </value>
        protected DayRandService DayRand { get; set; }

        /// <summary>
        /// Gets the year.
        /// 年
        /// </summary>
        /// <value>
        /// The year.
        /// </value>
        public int Year { get; private set; }

        /// <summary>
        /// Gets the month.
        /// 月
        /// </summary>
        /// <value>
        /// The month.
        /// </value>
        public int Month { get; private set; }

        /// <summary>
        /// Gets the day.
        /// 日
        /// </summary>
        /// <value>
        /// The day.
        /// </value>
        public int Day { get; private set; }

        /// <summary>
        /// Rands this instance.
        /// 随机生成时间方法
        /// 映射到虚方法中，扩展时，可重写
        /// </summary>
        /// <returns>
        /// 返回时间类型
        /// </returns>
        public virtual System.DateTime Rand()
        {
            this.Year = this.YearRand.Rand();
            this.Month = this.MonthRand.Rand();
            var thirtyOneMonth = new List<int>() { 1, 3, 5, 7, 8, 10, 12 };
            var thirtyMonth = new List<int>() { 4, 6, 9, 11 };

            if (this.DayRand != null && this.DayRand.Serial.Count > 0)
            {
                this.Day = this.DayRand.Rand();
            }
            else
            {
                if (thirtyMonth.Contains(this.Month))
                {
                    this.DayRand = new DayThirtyRandService();
                }
                else if (thirtyOneMonth.Contains(this.Month))
                {
                    this.DayRand = new DayThirtyOneRandService();
                }
                else
                {
                    if ((this.Year % 4) == 0 && (this.Year % 400) == 0 && this.Month == 2)
                    {
                        this.DayRand = new DayTwentyNineRandService();
                    }
                    else
                    {
                        this.DayRand = new DayTwentyEightRandService();
                    }
                }
                this.Day = this.DayRand.Rand();
            }
            return new System.DateTime(this.Year, this.Month, this.Day);
        }
    }
}
